home *** CD-ROM | disk | FTP | other *** search
- /*
- * tifflib.c - Copyright (c) 1987 by Bear River Associates, Inc.
- *
- * MPW C Version
- */
-
- /* Standard C Include files */
- #include "ErrNo.h"
- #include "StdIO.h"
-
- /* Primary Interface Files */
- #include "Types.h"
- #include "Resources.h"
- #include "Quickdraw.h"
- #include "Windows.h"
- #include "OSUtils.h"
-
- #include "ToolUtils.h"
- #include "TextEdit.h"
- #include "Controls.h"
-
- /* Other Interface files */
- #include "Dialogs.h"
- #include "Errors.h"
- #include "Events.h"
- #include "Files.h"
- #include "Memory.h"
- #include "Packages.h"
-
- /* Application-specific Include files */
- #include "tifflib.h"
-
- /* Local Routine Declarations */
- OSErr InsertTag();
- OSErr HdlInsertTag();
- OSErr DeleteTag();
- OSErr GStripArrays();
- OSErr PutStripArrays();
- OSErr GStripParams();
- void ParseTag();
- void SwapWord();
- void SwapLong();
-
- /* External Routine Declarations */
- OSErr AllocPtr();
- OSErr AllocMemory();
- OSErr AllocHandleSize();
-
- /* **************************************************************** */
-
- TIFFLoader()
- {
- }
-
- /* ------------------------------------------------------------------- */
-
- /*
- * Writes or re-writes the header; the value of dirOffset
- * is the offset of the first directory.
- */
-
- OSErr TWriteHeader(refNum, dirOffset, byteOrder)
- Int16 refNum;
- Int32 dirOffset; /* offset of first directory */
- Int16 byteOrder;
- {
- OSErr error;
- TiffHeader header;
- Int32 count;
-
- error = noErr;
-
- header.byteOrder = byteOrder;
- header.version = LEGAL_VERSION;
- header.dirOffset = dirOffset;
- if (byteOrder == INTEL)
- {
- SwapWord(&header.version);
- SwapLong(&header.dirOffset);
- }
-
- error = SetFPos(refNum, fsFromStart, 0L);
-
- count = sizeof(TiffHeader);
- if (error == noErr)
- error = FSWrite(refNum, &count, &header);
-
- return(error);
- }
-
- /* ------------------------------------------------------------------- */
-
- /*
- * Reads header, returns offset of the first image file directory and the
- * byte order of the file.
- */
-
- OSErr TReadHeader(refNum, dirOffset, byteOrder)
- Int16 refNum;
- Int32 *dirOffset;
- Int16 *byteOrder;
- {
- OSErr error;
- TiffHeader header;
- Int32 count;
-
- error = SetFPos(refNum, fsFromStart, 0L);
-
- count = sizeof(TiffHeader);
- if (error == noErr)
- error = FSRead(refNum, &count, &header);
-
- if (header.byteOrder == INTEL)
- SwapLong(&header.dirOffset);
- *dirOffset = header.dirOffset;
- *byteOrder = header.byteOrder;
-
- return(error);
- }
-
- /* ------------------------------------------------------------------- */
-
- /*
- * Add tag to list. If tag already present, update length and value.
- * This routine keeps tags in correct order in list.
- */
-
- OSErr TPutPtrTag(listHandle, tagNo, tagType, nVals, value)
- Handle listHandle;
- Int16 tagNo;
- Int16 tagType;
- Int32 nVals;
- unsigned char *value;
- {
- Int32 pointer;
- OSErr error;
-
- error = noErr;
-
- pointer = 0L;
- if (TFindTag(listHandle, &pointer, tagNo))
- error = DeleteTag(listHandle, pointer);
-
- if (error == noErr)
- error = InsertTag(listHandle, pointer, tagNo, tagType, nVals, value);
- return(error);
- }
-
- /* ------------------------------------------------------------------- */
-
- /*
- * Add tag to list. Value for tag is in a handle block.
- * If tag already present, update length and value.
- * This routine keeps tags in correct order in list.
- */
-
- OSErr TPutHdlTag(listHandle, tagNo, tagType, nVals, valueHdl)
- Handle listHandle;
- Int16 tagNo;
- Int16 tagType;
- Int32 nVals;
- unsigned char **valueHdl;
- {
- Int32 pointer;
- OSErr error;
-
- error = noErr;
-
- pointer = 0L;
- if (TFindTag(listHandle, &pointer, tagNo))
- error = DeleteTag(listHandle, pointer);
-
- if (error == noErr)
- error = HdlInsertTag(listHandle, pointer, tagNo, tagType,
- nVals, valueHdl);
- return(error);
- }
-
- /* ------------------------------------------------------------------- */
-
- /*
- * Searches list for tag of specified number.
- * If found, returns TRUE, and pointer contains offset of tag in list.
- * If not found, returns FALSE, and pointer contains offset in list where
- * tag would be inserted.
- */
-
- Boolean TFindTag(listHandle, pointer, tagNo)
- Handle listHandle;
- Int32 *pointer;
- Int16 tagNo;
- {
- Boolean done;
- Int32 listSize;
- Int16 thisTagNo;
- Int16 tagType;
- Int32 length;
- Int32 nVals;
-
- *pointer = 0L;
- listSize = GetHandleSize(listHandle);
-
- done = FALSE;
- while (*pointer < listSize && !done)
- {
- ParseTag(listHandle, *pointer, &thisTagNo, &tagType, &nVals);
- switch(tagType)
- {
- case BYTE:
- length = nVals * BYTESIZE;
- break;
- case ASCII:
- length = nVals * ASCIISIZE;
- break;
- case SHORT:
- length = nVals * SHORTSIZE;
- break;
- case LONG:
- length = nVals * LONGSIZE;
- break;
- case RATIONAL:
- length = nVals * RATSIZE;
- break;
- default:
- done = TRUE;
- break;
- }
- if (thisTagNo < tagNo)
- (*pointer) += 8 + length;
- else
- done = TRUE;
- }
-
- return(done && (tagNo == thisTagNo));
- }
-
- /* ------------------------------------------------------------------- */
-
- /*
- * Returns value of tag. Tag is specified by listHandle and pointer.
- */
-
- void TGetTag(listHandle, pointer, value, valueSize)
- Handle listHandle;
- Int32 pointer;
- Ptr value;
- Int32 valueSize;
- {
- Int16 tagNo;
- Int16 tagType;
- Int32 length;
- Int32 nVals;
- Int32 i;
- Ptr listPtr;
- Ptr valuePtr;
-
-
- ParseTag(listHandle, pointer, &tagNo, &tagType, &nVals);
- switch(tagType)
- {
- case BYTE:
- length = nVals * BYTESIZE;
- break;
- case ASCII:
- length = nVals * ASCIISIZE;
- break;
- case SHORT:
- length = nVals * SHORTSIZE;
- break;
- case LONG:
- length = nVals * LONGSIZE;
- break;
- case RATIONAL:
- length = nVals * RATSIZE;
- break;
- default:
- length = 0L;
- break;
- }
-
- valuePtr = value;
- listPtr = *listHandle + pointer + 8; /* DEREFERENCING HANDLE */
- for (i=0; i<length && i<valueSize; i++)
- *valuePtr++ = *listPtr++;
- }
-
- /* ------------------------------------------------------------------- */
-
- /*
- * Read tags from file, from directory at offset thisDirPointer.
- * Create and return a handle to the tag data. Return offset to next
- * directory in nextDirPointer.
- */
-
- OSErr TReadTags(refNum, byteOrder, listHandle, thisDirPointer, nextDirPointer)
- Int16 refNum;
- Int16 byteOrder;
- Handle *listHandle;
- Int32 thisDirPointer;
- Int32 *nextDirPointer;
- {
- OSErr error;
- Int32 count;
- Int16 entryCount;
- Int16 thisEntry;
- Int16 tagNo;
- Int16 tagType;
- Int32 nVals;
- Int32 length;
- Int32 valOffset;
- Int32 listPointer;
- Int32 nextDirEntry;
- Ptr tempBuffer;
- Int32 k;
- Handle tempHandle;
-
- *listHandle = NIL;
- error = AllocMemory(listHandle, 0L);
-
- if (error == noErr)
- error = SetFPos(refNum, fsFromStart, thisDirPointer);
-
- if (error == noErr)
- {
- count = sizeof(Int16);
- error = FSRead(refNum, &count, &entryCount);
- if (byteOrder == INTEL)
- SwapWord(&entryCount);
- }
-
-
- thisEntry = 0;
- listPointer = 0L;
- nextDirEntry = thisDirPointer + 2;
- while (thisEntry++ < entryCount && error == noErr)
- {
- error = SetFPos(refNum, fsFromStart, nextDirEntry);
- count = 2;
- if (error == noErr)
- error = FSRead(refNum, &count, &tagNo);
- if (byteOrder == INTEL)
- SwapWord(&tagNo);
- count = 2;
- if (error == noErr)
- error = FSRead(refNum, &count, &tagType);
- if (byteOrder == INTEL)
- SwapWord(&tagType);
- count = 4;
- if (error == noErr)
- error = FSRead(refNum, &count, &nVals);
- if (byteOrder == INTEL)
- SwapLong(&nVals);
- switch(tagType)
- {
- case BYTE:
- length = nVals * BYTESIZE;
- break;
- case ASCII:
- length = nVals * ASCIISIZE;
- break;
- case SHORT:
- length = nVals * SHORTSIZE;
- break;
- case LONG:
- length = nVals * LONGSIZE;
- break;
- case RATIONAL:
- length = nVals * RATSIZE;
- break;
- default:
- error = -3;
- break;
- }
- count = 4;
- if (error == noErr)
- error = FSRead(refNum, &count, &valOffset);
- if (length > 4)
- {
- if (byteOrder == INTEL)
- SwapLong(&valOffset);
- tempBuffer = NIL;
- if (error == noErr)
- error = AllocPtr(&tempBuffer, length);
- if (error == noErr)
- error = SetFPos(refNum, fsFromStart, valOffset);
- count = length;
- if (error == noErr)
- error = FSRead(refNum, &count, tempBuffer);
- if (error == noErr && byteOrder == INTEL)
- switch(tagType)
- {
- case SHORT:
- for (k=0; k<nVals; k++)
- SwapWord(&((Int16 *)tempBuffer)[k]);
- break;
- case LONG:
- for (k=0; k<nVals; k++)
- SwapLong(&((Int32 *)tempBuffer)[k]);
- break;
- case RATIONAL:
- for (k=0; k<nVals; k++)
- {
- SwapLong(&((Int32 *)tempBuffer)[2*k]);
- SwapLong(&((Int32 *)tempBuffer)[2*k + 1]);
- }
- break;
- }
- if (error == noErr)
- error = TPutPtrTag(*listHandle, tagNo, tagType, nVals, tempBuffer);
- if (tempBuffer != NIL)
- DisposPtr(tempBuffer);
- }
- else
- {
- if (byteOrder == INTEL)
- switch(tagType)
- {
- case SHORT:
- for (k=0; k<nVals; k++)
- SwapWord(&((Int16 *)&valOffset)[k]);
- break;
- case LONG:
- SwapLong(&valOffset);
- break;
- }
- if (error == noErr)
- error = TPutPtrTag(*listHandle, tagNo, tagType,
- nVals, &valOffset);
- }
- nextDirEntry += 12;
- }
-
- return(error);
- }
-
- /* ------------------------------------------------------------------- */
-
- /*
- * Write tag data from listHandle out to file, beginning at
- * offset *nextFileFree. Update nextFileFree to logical end-of-file.
- * Put nextDirPointer at end of tag directory as value of offset to
- * the next tag directory.
- */
-
- OSErr TWriteTags(refNum, byteOrder, nextFileFree, listHandle, nextDirPointer)
- Int16 refNum;
- Int16 byteOrder;
- Int32 *nextFileFree;
- Handle *listHandle;
- Int32 nextDirPointer;
- {
- OSErr error;
- Int32 count;
- Int32 listSize;
- Int16 tagNo;
- Int16 tagType;
- Int32 length;
- Int32 nVals;
- Int16 thisEntry;
- Int16 entryCount;
- Int32 listPointer;
- Int32 nextDirEntry;
- UInt32 valOffset;
- Int32 i;
- Int32 k;
- UInt16 temp16;
- UInt32 temp32;
- Ptr tempPtr;
- Handle tempHandle;
-
- error = noErr;
-
- listPointer = 0L;
- listSize = GetHandleSize(listHandle);
-
- /* count the number of directory entries (number of tags) */
- entryCount = 0;
- while (listPointer < listSize && error == noErr)
- {
- ParseTag(listHandle, listPointer, &tagNo, &tagType, &nVals);
- switch(tagType)
- {
- case BYTE:
- length = nVals * BYTESIZE;
- break;
- case ASCII:
- length = nVals * ASCIISIZE;
- break;
- case SHORT:
- length = nVals * SHORTSIZE;
- break;
- case LONG:
- length = nVals * LONGSIZE;
- break;
- case RATIONAL:
- length = nVals * RATSIZE;
- break;
- default:
- error = -3;
- break;
- }
- listPointer += 8 + length;
- entryCount++;
- }
-
- if (error == noErr)
- error = SetFPos(refNum, fsFromStart, *nextFileFree);
-
- count = 2;
- temp16 = entryCount;
- if (byteOrder == INTEL)
- SwapWord(&temp16);
- if (error == noErr)
- error = FSWrite(refNum, &count, &temp16);
-
- /* offset for the first tag to be written */
- nextDirEntry = *nextFileFree + 2;
- /* set nexFileFree to point past this IFD */
- *nextFileFree += 2 + entryCount * 12 + 4;
- count = entryCount * 12 + 4;
- /* expand file to fit IFD */
- if (error == noErr)
- error = SetEOF(refNum, *nextFileFree);
-
- /* write out the tags */
- thisEntry = 0;
- listPointer = 0L;
- while (thisEntry++ < entryCount && error == noErr)
- {
- error = SetFPos(refNum, fsFromStart, nextDirEntry);
- ParseTag(listHandle, listPointer, &tagNo, &tagType, &nVals);
- switch(tagType)
- {
- case BYTE:
- length = nVals * BYTESIZE;
- break;
- case ASCII:
- length = nVals * ASCIISIZE;
- break;
- case SHORT:
- length = nVals * SHORTSIZE;
- break;
- case LONG:
- length = nVals * LONGSIZE;
- break;
- case RATIONAL:
- length = nVals * RATSIZE;
- break;
- default:
- error = -3;
- break;
- }
- count = 2;
- temp16 = tagNo;
- if (byteOrder == INTEL)
- SwapWord(&temp16);
- if (error == noErr)
- error = FSWrite(refNum, &count, &temp16);
-
- count = 2;
- temp16 = tagType;
- if (byteOrder == INTEL)
- SwapWord(&temp16);
- if (error == noErr)
- error = FSWrite(refNum, &count, &temp16);
-
- count = 4;
- temp32 = nVals;
- if (byteOrder == INTEL)
- SwapLong(&temp32);
- if (error == noErr)
- error = FSWrite(refNum, &count, &temp32);
-
- if (length <= 4) /* put actual value in directory entry */
- {
- valOffset = 0L;
- TGetTag(listHandle, listPointer, &valOffset, length);
-
- count = 4;
- temp32 = valOffset;
- if (byteOrder == INTEL)
- {
- switch(tagType)
- {
- case SHORT:
- for (k=0; k<nVals; k++)
- SwapWord(&((Int16 *)&temp32)[k]);
- break;
- case LONG:
- SwapLong(&temp32);
- break;
- }
- }
- if (error == noErr)
- error = FSWrite(refNum, &count, &temp32);
- }
- else /* offset of value goes in directory entry */
- {
- valOffset = *nextFileFree;
- count = 4;
- temp32 = valOffset;
- if (byteOrder == INTEL)
- SwapLong(&temp32);
- if (error == noErr)
- error = FSWrite(refNum, &count, &temp32);
- if (error == noErr)
- error = SetFPos(refNum, fsFromStart, *nextFileFree);
- count = length;
- tempPtr = NIL;
- if (error == noErr)
- error = AllocPtr(&tempPtr, length);
- if (error == noErr)
- TGetTag(listHandle, listPointer, tempPtr, length);
- if (error == noErr && byteOrder == INTEL)
- switch(tagType)
- {
- case SHORT:
- for (k=0; k<nVals; k++)
- SwapWord(&((Int16 *)tempPtr)[k]);
- break;
- case LONG:
- for (k=0; k<nVals; k++)
- SwapLong(&((Int32 *)tempPtr)[k]);
- break;
- case RATIONAL:
- for (k=0; k<nVals; k++)
- {
- SwapLong(&((Int32 *)tempPtr)[2*k]);
- SwapLong(&((Int32 *)tempPtr)[2*k + 1]);
- }
- break;
- }
- if (error == noErr)
- error = FSWrite(refNum, &count, tempPtr);
- *nextFileFree += length;
- if (tempPtr != NIL)
- DisposPtr(tempPtr);
- }
- nextDirEntry += 12;
- listPointer += 8 + length;
- }
-
- if (error == noErr)
- error = SetFPos(refNum, fsFromStart, nextDirEntry);
- count = 4;
- temp32 = nextDirPointer;
- if (byteOrder == INTEL)
- SwapLong(&temp32);
- if (error == noErr)
- error = FSWrite(refNum, &count, &temp32);
-
- return(error);
- }
-
- /* ------------------------------------------------------------------- */
-
- /*
- * Reads in "numLines" lines from the file starting with line number
- * "startLine". The data for the lines will be places at the address
- * specified by bufferPtr.
- */
- OSErr TReadImage(refNum, listHandle, startLine, bufferPtr, numLines, plane)
- Int16 refNum;
- Handle listHandle;
- Int32 startLine;
- Ptr bufferPtr;
- Int32 numLines;
- Int16 plane; /* ignored, for now */
- {
- Handle countHandle;
- Handle offsetHandle;
- OSErr error;
- Int32 pointer;
- Int32 tRowsPerStrip;
- Int16 tRowBytes;
- Int16 bitsPerSample;
- Int16 imageWidth;
- Int16 imageLength;
- Int16 compressType;
- Int16 firstStrip;
- Int16 lastStrip;
- Int16 stripNum;
- Ptr stripPtr;
- Ptr dummyPtr;
- Int32 stripSize;
- Int32 stripOffset;
- Ptr srcPtr;
- Ptr dstPtr;
- register Ptr rSrcPtr;
- register Ptr rDstPtr;
- Int32 count;
- Int16 i;
- Int32 thisLine;
- Handle tempHandle;
-
- error = GStripArrays(listHandle, &offsetHandle, &countHandle);
-
- if (error == noErr)
- error = GStripParams(listHandle, &tRowsPerStrip,
- &imageWidth, &imageLength, &compressType, &bitsPerSample);
-
- tRowBytes = ((Int32)imageWidth * bitsPerSample + 7) / 8;
- /* NOTE! this can be an odd number, unlike bitMap.rowBytes */
-
- dummyPtr = NIL;
- if (error == noErr)
- error = AllocPtr(&dummyPtr, (Int32)tRowBytes);
-
- if (error == noErr)
- {
- firstStrip = startLine / tRowsPerStrip;
- lastStrip = (startLine + numLines - 1) / tRowsPerStrip;
- thisLine = firstStrip * tRowsPerStrip;
- for (stripNum = firstStrip; stripNum <= lastStrip && error == noErr;
- stripNum++)
- {
- stripSize = (*(Int32 **)countHandle)[stripNum];
- stripOffset = (*(Int32 **)offsetHandle)[stripNum];
- stripPtr = NIL;
- error = AllocPtr(&stripPtr, stripSize);
- if (error == noErr)
- error = SetFPos(refNum, fsFromStart, stripOffset);
- if (error == noErr)
- {
- count = stripSize;
- error = FSRead(refNum, &count, stripPtr);
- }
- if (error == noErr)
- {
- srcPtr = stripPtr;
- while (srcPtr < stripPtr + stripSize &&
- thisLine < startLine + numLines && error == noErr)
- {
- if (thisLine < startLine)
- dstPtr = dummyPtr;
- else if (thisLine == startLine)
- dstPtr = bufferPtr;
- switch (compressType)
- {
- case 1:
- rSrcPtr = srcPtr;
- rDstPtr = dstPtr;
- for (i=0; i<tRowBytes; i++)
- *rDstPtr++ = *rSrcPtr++;
- srcPtr = rSrcPtr;
- dstPtr = rDstPtr;
- break;
-
- case 2:
- error = HDecode(&dstPtr, &srcPtr, imageWidth);
- break;
-
- default:
- error = -3;
- break;
- }
- thisLine++;
- }
- }
- if (stripPtr != NIL)
- DisposPtr(stripPtr);
- }
- }
-
- if (offsetHandle != NIL)
- DisposHandle(offsetHandle);
- if (countHandle != NIL)
- DisposHandle(countHandle);
- if (dummyPtr != NIL)
- DisposPtr(dummyPtr);
-
- return(error);
- }
-
- /* ------------------------------------------------------------------- */
-
- /*
- * Writes image data for ONE strip. startpos must be start of a strip.
- * numLines must be <= tRowsPerStrip.
- * Strip parameters (rowsPerStrip, imageWidth,
- * compressType and imageLength) must already have tags
- */
-
- OSErr TWriteImageStrip(refNum, nextFileFree, listHandle,
- startLine, numLines, bufferPtr, plane)
- Int16 refNum;
- Int32 *nextFileFree;
- Handle listHandle;
- Int32 startLine;
- Int32 numLines;
- Ptr bufferPtr;
- Int16 plane;
- {
- OSErr error;
- OSErr tempErr;
- Int32 ** offsetHandle;
- Int32 ** countHandle;
- Int16 stripNum;
- Int16 numStrips;
- Int16 row;
- Int16 i;
- Int32 tRowsPerStrip;
- Int16 tRowBytes;
- Int16 bitsPerSample;
- Int16 imageWidth;
- Int16 imageLength;
- Int16 compressType;
- Int32 stripSize;
- Int32 count;
- Ptr srcPtr;
- Ptr dstPtr;
- register Ptr rSrcPtr;
- register Ptr rDstPtr;
- Ptr rowBuffer;
- Int32 thisLine;
- Handle tempHandle;
-
- error = noErr;
- if (GStripArrays(listHandle, &offsetHandle, &countHandle) != noErr)
- { /* if offsetHandle and countHandle don't exist, then create them */
- error = AllocMemory(&offsetHandle, 0L);
- if (error == noErr)
- error = AllocMemory(&countHandle, 0L);
- }
- if (error == noErr)
- error = GStripParams(listHandle, &tRowsPerStrip, &imageWidth,
- &imageLength, &compressType, &bitsPerSample);
-
- if (tRowsPerStrip > imageLength)
- tRowsPerStrip = imageLength;
-
- stripNum = startLine / tRowsPerStrip;
-
- if (error == noErr)
- {
- numStrips = GetHandleSize(offsetHandle) / sizeof(Int32);
- if (stripNum >= numStrips)
- {
- error = AllocHandleSize(offsetHandle,
- (Size)(stripNum + 1) * sizeof(Int32));
- if (error == noErr)
- error = AllocHandleSize(countHandle,
- (Size)(stripNum + 1) * sizeof(Int32));
- if (error == noErr)
- for (i=numStrips; i<stripNum; i++)
- (*countHandle)[i] = 0L;
- }
- }
-
- tRowBytes = (imageWidth * bitsPerSample + 7) / 8;
- /* NOTE! this can be an odd number, unlike bitMap.rowBytes */
-
- rowBuffer = NIL;
- if (error == noErr)
- error = AllocPtr(&rowBuffer, 2 * (Int32)tRowBytes);
-
- if (error == noErr)
- {
- (*offsetHandle)[stripNum] = *nextFileFree;
- stripSize = 0L;
- srcPtr = bufferPtr;
- error = SetFPos(refNum, fsFromStart, *nextFileFree);
- for (row=0; row<tRowsPerStrip && row<numLines && error == noErr; row++)
- {
- dstPtr = rowBuffer;
- switch (compressType)
- {
- case 1:
- rSrcPtr = srcPtr;
- rDstPtr = dstPtr;
- for (i=0; i<tRowBytes; i++)
- *rDstPtr++ = *rSrcPtr++;
- srcPtr = rSrcPtr;
- dstPtr = rDstPtr;
- count = tRowBytes;
- break;
-
- case 2:
- error = HEncode(&srcPtr, &dstPtr, imageWidth);
- count = dstPtr - rowBuffer;
- break;
-
- default:
- error = -3;
- break;
- }
- if (error == noErr)
- error = FSWrite(refNum, &count, rowBuffer);
- *nextFileFree += count;
- stripSize += count;
- }
- (*countHandle)[stripNum] = stripSize;
- }
-
- if (rowBuffer != NIL)
- DisposPtr(rowBuffer);
-
- tempErr = PutStripArrays(listHandle, offsetHandle, countHandle);
- if (error == noErr)
- error = tempErr;
- return(error);
- }
-
- /* ---------------------------------------------------------------- */
-
- void TFixOddRowBytes(bitMap)
- BitMap *bitMap;
- {
- register Ptr dstPtr;
- register Ptr srcPtr;
- Int32 nLines;
- Int16 line;
- Int16 k;
-
- nLines = bitMap->bounds.bottom - bitMap->bounds.top;
- srcPtr = bitMap->baseAddr + nLines * (bitMap->rowBytes - 1) - 1;
- dstPtr = bitMap->baseAddr + nLines * bitMap->rowBytes - 2;
- for (line=nLines; line>0; line--)
- {
- for (k=0; k<bitMap->rowBytes-1; k++)
- *dstPtr-- = *srcPtr--;
- dstPtr--;
- }
- }
-
- /* ---------------------------------------------------------------- */
-
- void TUnfixOddRowBytes(bitMap)
- BitMap *bitMap;
- {
- register Ptr dstPtr;
- register Ptr srcPtr;
- Int32 nLines;
- Int16 line;
- Int16 k;
-
- nLines = bitMap->bounds.bottom - bitMap->bounds.top;
- srcPtr = bitMap->baseAddr;
- dstPtr = bitMap->baseAddr;
- for (line=0; line<nLines; line++)
- {
- for (k=0; k<bitMap->rowBytes-1; k++)
- *dstPtr++ = *srcPtr++;
- srcPtr++;
- }
- }
-
- /* ------------------------------------------------------------------- */
- /* Local Subroutines */
- /* ------------------------------------------------------------------- */
-
- /*
- * Remove the tag beginning at the specified offset. Reduce the size
- * of the list accordingly.
- */
-
- static OSErr DeleteTag(listHandle, pointer)
- Handle listHandle;
- Int32 pointer;
- {
- Int32 listSize;
- Int16 tagNo;
- Int16 tagType;
- Int32 length;
- Int32 nVals;
- Int16 tagSize;
- unsigned char *listPtr;
- Int32 i;
- OSErr error;
- Handle tempHandle;
-
- listSize = GetHandleSize(listHandle);
- ParseTag(listHandle, pointer, &tagNo, &tagType, &nVals);
- switch(tagType)
- {
- case BYTE:
- length = nVals * BYTESIZE;
- break;
- case ASCII:
- length = nVals * ASCIISIZE;
- break;
- case SHORT:
- length = nVals * SHORTSIZE;
- break;
- case LONG:
- length = nVals * LONGSIZE;
- break;
- case RATIONAL:
- length = nVals * RATSIZE;
- break;
- }
- tagSize = length + 8;
-
- listPtr = *listHandle; /* DEREFERENCING HANDLE */
- for (i=pointer; i<listSize-tagSize; i++)
- listPtr[i] = listPtr[i + tagSize];
-
- error = AllocHandleSize(listHandle, listSize - tagSize);
- return(error);
- }
-
- /* ------------------------------------------------------------------- */
-
- /*
- * Insert tag in list. This routine does not check for duplicates.
- */
-
- static OSErr InsertTag(listHandle, pointer, tagNo, tagType, nVals, value)
- Handle listHandle;
- Int32 pointer;
- Int16 tagNo;
- Int16 tagType;
- Int32 nVals;
- unsigned char *value;
- {
- OSErr error;
- Int32 listSize;
- Int32 tagSize;
- unsigned char *listPtr;
- Int32 i;
- Int32 length;
- Handle tempHandle;
-
- listSize = GetHandleSize(listHandle);
- switch(tagType)
- {
- case BYTE:
- length = nVals * BYTESIZE;
- break;
- case ASCII:
- length = nVals * ASCIISIZE;
- break;
- case SHORT:
- length = nVals * SHORTSIZE;
- break;
- case LONG:
- length = nVals * LONGSIZE;
- break;
- case RATIONAL:
- length = nVals * RATSIZE;
- break;
- default:
- error = -3;
- break;
- }
- tagSize = length + 8;
- error = AllocHandleSize(listHandle, listSize + tagSize);
-
- if (error == noErr)
- {
- listPtr = *listHandle; /* DEREFERENCING HANDLE */
- for (i=listSize+tagSize-1; i>=pointer+tagSize; i--)
- listPtr[i] = listPtr[i - tagSize];
- listPtr += pointer;
- *listPtr++ = (tagNo >> 8) & 0xff;
- *listPtr++ = (tagNo) & 0xff;
- *listPtr++ = (tagType >> 8) & 0xff;
- *listPtr++ = (tagType) & 0xff;
- *listPtr++ = (nVals >> 24) & 0xff;
- *listPtr++ = (nVals >> 16) & 0xff;
- *listPtr++ = (nVals >> 8) & 0xff;
- *listPtr++ = (nVals) & 0xff;
- for (i=0; i<length; i++)
- *listPtr++ = value[i];
- }
-
- return(error);
- }
-
- /* ------------------------------------------------------------------- */
-
- /*
- * Insert tag in list. value is stored in a handle block.
- * This routine does not check for duplicates.
- */
-
- static OSErr HdlInsertTag(listHandle, pointer, tagNo, tagType, nVals, valueHdl)
- Handle listHandle;
- Int32 pointer;
- Int16 tagNo;
- Int16 tagType;
- Int32 nVals;
- unsigned char **valueHdl;
- {
- OSErr error;
- Int32 listSize;
- Int32 tagSize;
- unsigned char *listPtr;
- Int32 i;
- Int32 length;
- Handle tempHandle;
-
- listSize = GetHandleSize(listHandle);
- switch(tagType)
- {
- case BYTE:
- length = nVals * BYTESIZE;
- break;
- case ASCII:
- length = nVals * ASCIISIZE;
- break;
- case SHORT:
- length = nVals * SHORTSIZE;
- break;
- case LONG:
- length = nVals * LONGSIZE;
- break;
- case RATIONAL:
- length = nVals * RATSIZE;
- break;
- default:
- error = -3;
- break;
- }
- tagSize = length + 8;
- error = AllocHandleSize(listHandle, listSize + tagSize);
-
- if (error == noErr)
- {
- listPtr = *listHandle; /* DEREFERENCING HANDLE */
- for (i=listSize+tagSize-1; i>=pointer+tagSize; i--)
- listPtr[i] = listPtr[i - tagSize];
- listPtr += pointer;
- *listPtr++ = (tagNo >> 8) & 0xff;
- *listPtr++ = (tagNo) & 0xff;
- *listPtr++ = (tagType >> 8) & 0xff;
- *listPtr++ = (tagType) & 0xff;
- *listPtr++ = (nVals >> 24) & 0xff;
- *listPtr++ = (nVals >> 16) & 0xff;
- *listPtr++ = (nVals >> 8) & 0xff;
- *listPtr++ = (nVals) & 0xff;
- for (i=0; i<length; i++)
- *listPtr++ = (&**valueHdl)[i];
- }
-
- return(error);
- }
-
- /* ------------------------------------------------------------------- */
-
- static void ParseTag(listHandle, pointer, tagNo, tagType, nVals)
- Handle listHandle;
- Int32 pointer;
- Int16 *tagNo;
- Int16 *tagType;
- Int32 *nVals;
- {
- unsigned char *listPtr;
-
- listPtr = *listHandle + pointer; /* DEREFERENCING HANDLE */
- *tagNo = ((UInt16)listPtr[0] << 8) + (UInt16)listPtr[1];
- *tagType = ((UInt16)listPtr[2] << 8) + (UInt16)listPtr[3];
- *nVals = ((UInt32)listPtr[4] << 24) + (UInt32)(listPtr[5] << 16) +
- ((UInt32)listPtr[6] << 8) + (UInt32)listPtr[7];
- }
-
- /* ------------------------------------------------------------------- */
-
- /*
- * Create and return handles to arrays containg the strip byte counts
- * and strip offsets
- */
-
- static OSErr GStripArrays(listHandle, offsetHandle, countHandle)
- Handle listHandle;
- Handle *offsetHandle;
- Handle *countHandle;
- {
- OSErr error;
- Int32 pointer;
- Int16 tagNo;
- Int16 tagType;
- Int32 length;
- Int32 numOffsets;
- Int32 nVals;
- Int32 tRowsPerStrip;
- Int16 imageWidth;
- Int16 imageLength;
- Int16 compressType;
- Int16 bitsPerSample;
- Int32 theByteCount;
- Int32 i;
- UInt8 *temp8Ptr;
- UInt16 *temp16Ptr;
- UInt32 *temp32Ptr;
-
- *countHandle = NIL;
- *offsetHandle = NIL;
-
- error = noErr;
-
-
- /* .................................... */
-
- if (error == noErr)
- error = TFindTag(listHandle, &pointer, STRIP_OFFSETS_TAG) ?
- noErr : -3;
-
- if (error == noErr)
- {
- ParseTag(listHandle, pointer, &tagNo, &tagType, &numOffsets);
- length = numOffsets * LONGSIZE;
- error = AllocMemory(offsetHandle, length);
- }
-
- if (error == noErr)
- {
- HLock(*offsetHandle);
- TGetTag(listHandle, pointer, **offsetHandle, length);
- /* convert array bytes or shorts to array of longs in place */
- switch(tagType)
- {
- case BYTE:
- /* HANDLE DEREFERENCE */
- temp8Ptr = (*(UInt8 **)(*offsetHandle)) + numOffsets - 1;
- temp32Ptr = (*(UInt32 **)(*offsetHandle)) + numOffsets - 1;
- for (i = numOffsets - 1; i >= 0; i--)
- *temp32Ptr-- = *temp8Ptr--;
- break;
- case SHORT:
- /* HANDLE DEREFERENCE */
- temp16Ptr = (*(UInt16 **)(*offsetHandle)) + numOffsets - 1;
- temp32Ptr = (*(UInt32 **)(*offsetHandle)) + numOffsets - 1;
- for (i = numOffsets - 1; i >= 0; i--)
- *temp32Ptr-- = *temp16Ptr--;
- break;
- case LONG:
- break;
- default:
- error = -3;
- break;
- }
- HUnlock(*offsetHandle);
- }
-
- /* .................................... */
-
- if (error == noErr)
- {
- error = TFindTag(listHandle, &pointer, STRIP_BYTE_COUNTS_TAG) ? noErr : -3;
- if (error == noErr)
- { /* STRIP_BYTE_COUNTS_TAG exists */
- ParseTag(listHandle, pointer, &tagNo, &tagType, &nVals);
- length = nVals * LONGSIZE;
- error = AllocMemory(countHandle, length);
- if (error == noErr)
- {
- HLock(*countHandle);
- TGetTag(listHandle, pointer, **countHandle, length);
- /* convert array bytes or shorts to array of longs in place */
- switch(tagType)
- {
- case BYTE:
- /* HANDLE DEREFERENCE */
- temp8Ptr = (*(UInt8 **)(*countHandle)) + nVals - 1;
- temp32Ptr = (*(UInt32 **)(*countHandle)) + nVals - 1;
- for (i = nVals - 1; i >= 0; i--)
- *temp32Ptr-- = *temp8Ptr--;
- break;
- case SHORT:
- /* HANDLE DEREFERENCE */
- temp16Ptr = (*(UInt16 **)(*countHandle)) + nVals - 1;
- temp32Ptr = (*(UInt32 **)(*countHandle)) + nVals - 1;
- for (i = nVals - 1; i >= 0; i--)
- *temp32Ptr-- = *temp16Ptr--;
- break;
- case LONG:
- break;
- default:
- error = -3;
- break;
- }
- HUnlock(*countHandle);
- }
- }
- else
- { /* STRIP_BYTE_COUNTS_TAG does not exist */
- /* we are ok if file is not compressed and there is only one strip */
- error = GStripParams(listHandle, &tRowsPerStrip, &imageWidth, &imageLength,
- &compressType, &bitsPerSample);
- /* nVals and length determined above */
-
- if (error == noErr && compressType == 1 && numOffsets == 1)
- { /* OK. fake the count array */
- error = AllocMemory(countHandle, length);
- if (error == noErr)
- {
- theByteCount = (Int32)imageWidth * (Int32)imageLength *
- (Int32)bitsPerSample / 8L;
- **(Int32 **)(*countHandle) = theByteCount;
- }
- }
- else
- error = -3;
- }
- }
-
-
- /* .................................... */
-
- return(error);
- }
-
- /* ------------------------------------------------------------------- */
-
- /*
- * Delete old tags (if they exist) and add new tags for
- * StripByteCounts and StripOffsets. In all cases, offsetHandle and
- * countHandle are disposed, if they are not NIL
- */
-
- static OSErr PutStripArrays(listHandle, offsetHandle, countHandle)
- Handle listHandle;
- Handle offsetHandle;
- Handle countHandle;
- {
- OSErr error;
- Int32 pointer;
- Int16 tagNo;
- Int16 tagType;
- Int32 length;
- Int32 nVals;
-
- if (TFindTag(listHandle, &pointer, STRIP_BYTE_COUNTS_TAG))
- DeleteTag(listHandle, pointer);
-
- if (TFindTag(listHandle, &pointer, STRIP_OFFSETS_TAG))
- DeleteTag(listHandle, pointer);
-
- error = countHandle == NIL ? -3 : noErr;
- if (error == noErr)
- {
- length = GetHandleSize(countHandle);
- nVals = length / LONGSIZE;
- /*MoveHHi(countHandle);
- HLock(countHandle);*/
- error = TPutHdlTag(listHandle, STRIP_BYTE_COUNTS_TAG, LONG,
- nVals, countHandle);
- /*HUnlock(countHandle);*/
- }
-
- if (error == noErr)
- error = offsetHandle == NIL ? -3 : noErr;
-
- if (error == noErr)
- {
- length = GetHandleSize(offsetHandle);
- nVals = length / LONGSIZE;
- /*MoveHHi(offsetHandle);
- HLock(offsetHandle);*/
- error = TPutHdlTag(listHandle, STRIP_OFFSETS_TAG, LONG,
- nVals, offsetHandle);
- /*HUnlock(offsetHandle);*/
- }
-
- if (countHandle != NIL)
- DisposHandle(countHandle);
- if (offsetHandle != NIL)
- DisposHandle(offsetHandle);
-
- return(error);
- }
-
-
- /* ------------------------------------------------------------------- */
-
- /*
- * Read data from the tag data list (listHandle) and return the
- * values. If the tags are missing, return -3 as error.
- */
-
- static OSErr GStripParams(listHandle, tRowsPerStrip, imageWidth, imageLength,
- compressType, bitsPerSample)
- Handle listHandle;
- Int32 *tRowsPerStrip;
- Int16 *imageWidth;
- Int16 *imageLength;
- Int16 *compressType;
- Int16 *bitsPerSample;
- {
- OSErr error;
- OSErr tempError;
- Int32 pointer;
-
- tempError = TFindTag(listHandle, &pointer, ROWS_PER_STRIP_TAG) ?
- noErr : -3;
- if (tempError == noErr)
- TGetTag(listHandle, pointer, tRowsPerStrip, (Int32)LONGSIZE);
- else
- *tRowsPerStrip = 0x40000000; /* default */
-
- tempError = TFindTag(listHandle, &pointer, BITS_PER_SAMPLE_TAG) ?
- noErr : -3;
- if (tempError == noErr)
- TGetTag(listHandle, pointer, bitsPerSample, (Int32)SHORTSIZE);
- else
- *bitsPerSample = 1; /* default */
-
- tempError = TFindTag(listHandle, &pointer, COMPRESSION_TAG) ?
- noErr : -3;
-
- if (tempError == noErr)
- TGetTag(listHandle, pointer, compressType, (Int32)SHORTSIZE);
- else
- *compressType = 1; /* default */
-
- error = TFindTag(listHandle, &pointer, IMAGE_WIDTH_TAG) ?
- noErr : -3;
-
- if (error == noErr)
- TGetTag(listHandle, pointer, imageWidth, (Int32)SHORTSIZE);
-
- if (error == noErr)
- error = TFindTag(listHandle, &pointer, IMAGE_LENGTH_TAG) ?
- noErr : -3;
-
- if (error == noErr)
- TGetTag(listHandle, pointer, imageLength, (Int32)SHORTSIZE);
-
-
- return(error);
- }
-
- /* ------------------------------------------------------------------- */
-
- void SwapWord(val)
- UInt16 *val;
- {
- *val = (*val >> 8) + (*val << 8);
- }
-
- /* ------------------------------------------------------------------- */
-
- void SwapLong(val)
- UInt16 val[2];
- {
- UInt16 temp;
-
- temp = val[0];
- val[0] = (val[1] >> 8) + (val[1] << 8);
- val[1] = (temp >> 8) + (temp << 8);
- }
-
- /* ------------------------------------------------------------------- */
-